package fr.umlv.m2.jee.pmlv.persistence.cursus.dao;

import org.springframework.stereotype.Repository;
import fr.umlv.m2.jee.pmlv.framework.dao.hibernate.AbstractHibernateDAO;
import fr.umlv.m2.jee.pmlv.persistence.cursus.Cursus;
import fr.umlv.m2.jee.pmlv.persistence.cursus.Specialty;
import fr.umlv.m2.jee.pmlv.persistence.cursus.SpecialtySubject;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.persistence.Query;

/**
 * DAO for the class {@link Cursus} with the framework Hibernate.
 * This class implements {@link ICursusDAO}.
 * @author jenseric
 */
@Repository("hibernateCursusDAO")
public class HibernateCursusDAO extends AbstractHibernateDAO<Long, Cursus>  implements ICursusDAO {

    @Override
    public List<Cursus> findCursusByProfessorUidAndByYear(String uid, int year) {
        String query = "select distinct c from Cursus c, Specialty s, UserSubject us "
                + "inner join s.specialtySubject as sub "
                + "where us.primaryKey.uid='"+uid+"' and us.primaryKey.subject.id=sub.subject.id and sub.year="+year+" and s.cursus.id=c.id";
        List<Cursus> cursus = findByQuery(query);
        for(Cursus c:cursus)
        {
            query = "select distinct s from Specialty s, UserSubject us "
                + "inner join s.specialtySubject as sub "
                + "where us.primaryKey.uid='"+uid+"' and us.primaryKey.subject.id=sub.subject.id and sub.year="+year+" and s.cursus.id="+c.getId();
            Query result = getEntityManager().createQuery(query);
            Set<Specialty> specialties = new HashSet((List< Specialty >)result.getResultList());
            for(Specialty s:specialties)
            {
                query = "select sub from Specialty s, UserSubject us "
                + "inner join s.specialtySubject as sub "
                + "where us.primaryKey.uid='"+uid+"' and us.primaryKey.subject.id=sub.subject.id and sub.year="+year+" and s.id="+s.getId();
                result = getEntityManager().createQuery(query);
                List< SpecialtySubject > tmp = (List< SpecialtySubject >)result.getResultList();
                Set<SpecialtySubject> subjects = new TreeSet(new Comparator<SpecialtySubject>() {
                    @Override
                    public int compare(SpecialtySubject o1, SpecialtySubject o2) {
                        if(o1.getSemester()==o2.getSemester())
                            return new Long(o1.getId()).compareTo( new Long(o2.getId()));
                        else
                            return new Integer(o1.getSemester()).compareTo( new Integer(o2.getSemester()));
                    }
                });
                subjects.addAll(tmp);
                s.setSpecialtySubject(subjects);
            }
            c.setSpecialties(specialties);
        }
        return cursus;
    }

    @Override
    public List<Cursus> findCursusByStudentUidAndByYear(String uid, int year) {
        String query = "select distinct c from Cursus c, Specialty s, UserSpecialty us "
                + "where us.primaryKey.uid='"+uid+"' and us.primaryKey.year="+year+" and us.primaryKey.specialty.id=s.id and s.cursus.id=c.id";
        List<Cursus> cursus = findByQuery(query);
        for(Cursus c:cursus)
        {
            query = "select distinct s from Specialty s, UserSpecialty us "
                + "where us.primaryKey.uid='"+uid+"' and us.primaryKey.specialty.id=s.id and us.primaryKey.year="+year+" and s.cursus.id="+c.getId();
            Query result = getEntityManager().createQuery(query);
            Set<Specialty> specialties = new HashSet((List< Specialty >)result.getResultList());
            for(Specialty s:specialties)
            {
                query = "select distinct sub from Specialty s, UserSpecialty us "
                + "inner join s.specialtySubject as sub "
                + "where us.primaryKey.uid='"+uid+"' and us.primaryKey.specialty.id=s.id and sub.year="+year+" and s.id="+s.getId();
                result = getEntityManager().createQuery(query);
                List< SpecialtySubject > tmp = (List< SpecialtySubject >)result.getResultList();
                Set<SpecialtySubject> subjects = new TreeSet(new Comparator<SpecialtySubject>() {
                    @Override
                    public int compare(SpecialtySubject o1, SpecialtySubject o2) {
                        if(o1.getSemester()==o2.getSemester())
                            return new Long(o1.getId()).compareTo( new Long(o2.getId()));
                        else
                            return new Integer(o1.getSemester()).compareTo( new Integer(o2.getSemester()));
                    }
                });
                subjects.addAll(tmp);
                s.setSpecialtySubject(subjects);
            }
            c.setSpecialties(specialties);
        }
        return cursus;
    }

    @Override
    public Cursus findCursusBySubjectId(Long id) {
        String query = "select distinct s.cursus from Specialty s, SpecialtySubject spesub "
                + "where spesub.subject.id="+id+" and spesub.specialty.id=s.id";
        Cursus cursus = findEntityByQuery(query);
        return cursus;
    }
}



